
//  ApiProxy.swift
//  SearchGithubUserInfo
//
//  Created by menhao on 17/5/15.
//  Copyright © 2017年 menhao. All rights reserved.
//
import Foundation
import Alamofire


@objc public enum APIResponseDataType: Int {
    case Json
    case UTF8String
    case RawData
}

typealias SuccessCallBack = (_ responseObj: AnyObject, _ requestId: NSNumber)->(Void)
typealias FailedCallBack = (_ responseError: NSError, _ requestId: NSNumber)->(Void)

class ApiProxy {
    
    //MARK: api call function
    func makeRestGetRequestForUrl(url: String, parameters: Dictionary<String, AnyObject>?, responseDataType: APIResponseDataType, header: HTTPHeaders, successedCallBack: @escaping SuccessCallBack, failedCallBack: @escaping FailedCallBack) -> NSNumber {
        
        return callApiWithMethod(method: "GET", URLString: url, parameters: parameters, encoding: JSONEncoding() as ParameterEncoding, responseDataType: responseDataType,header: header, successCallBack: successedCallBack, failedCallBack: failedCallBack)
    }
    
    func makeRestPostRequestForUrl(url: String, parameters: Dictionary<String, AnyObject>?, responseDataType: APIResponseDataType, header: HTTPHeaders,successedCallBack: @escaping SuccessCallBack, failedCallBack: @escaping FailedCallBack) -> NSNumber {
      
        return callApiWithMethod(method: "POST", URLString: url, parameters: parameters, encoding:URLEncoding() as ParameterEncoding, responseDataType: responseDataType, header: header, successCallBack: successedCallBack, failedCallBack: failedCallBack)
    }
    
    //MARK: - request collection manuplation
    func cancellRequestForId(requestId: NSNumber) {
        guard let request = self.storedRequests[requestId] else{
            return
        }
        //        if let req = request {
        request.cancel()
        self.storedRequests.removeValue(forKey: requestId)
        //        }
    }
    
    func cancellRequestsWithIdList(idList: Array<NSNumber>) {
        for num in idList {
            self.cancellRequestForId(requestId: num)
        }
    }
    
    func cancellAllRequest() {
        for req in self.storedRequests.values {
            req.cancel()
        }
        
        self.storedRequests.removeAll()
    }
    func configureAlamofire() {
        Alamofire.SessionManager.default.session.configuration.timeoutIntervalForRequest = 10 // in seconds
        Alamofire.SessionManager.default.session.configuration.timeoutIntervalForResource = 10 // in seconds
    }
    static let sharedSessionManager: Alamofire.SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 10
        configuration.timeoutIntervalForResource = 10
        return Alamofire.SessionManager(configuration: configuration)
    }()
    
    

    

    
    //proxy to alamofire framework
    func callApiWithMethod(method: String, URLString: String, parameters: [String : AnyObject]?, encoding: ParameterEncoding, responseDataType: APIResponseDataType,header: HTTPHeaders?, successCallBack: @escaping SuccessCallBack, failedCallBack: @escaping FailedCallBack) -> NSNumber {
        
            let requestId = generateRequestId()
            var request = URLRequest(url: URL.init(string:URLString)!)
            request.httpMethod = method
            request.allHTTPHeaderFields = header
            //超时时间设置
            request.timeoutInterval = 30
            do {

                request = try encoding.encode(request, with: parameters)
                //转换成功
                
            } catch {
                //转换不成功
                if parameters != nil{
                    let err = NSError.init(domain: "您的参数格式不正确", code: -8888, userInfo: ["info":"您的参数格式不正确"])
                    failedCallBack(err, 999)
                    return 999
                }

            }

      
        var apiRequest: DataRequest
        switch responseDataType {
        case .Json:
            apiRequest = Alamofire.request(request).responseJSON(completionHandler: { (urlResponse) in
                self.requestFinished(urlResponse: urlResponse, requestId: requestId, successCallBack: successCallBack, failedCallBack: failedCallBack)
            })
            
            
        case .UTF8String:
            
            apiRequest = Alamofire.request(request).responseString(completionHandler: { (urlResponse) in
                self.requestFinished(urlResponse: urlResponse, requestId: requestId, successCallBack: successCallBack, failedCallBack: failedCallBack)
            })
            
        case .RawData:
            apiRequest =  Alamofire.request(request).responseData(completionHandler: { (urlResponse) in
                self.requestFinished(urlResponse: urlResponse, requestId: requestId, successCallBack: successCallBack, failedCallBack: failedCallBack)
            })
            
        }
        
            self.storedRequests[requestId] = apiRequest
        
            return requestId
        
        

    }
    //MARK: - 照片上传的封装
    ///
    /// - Parameters:
    ///   - urlString: 服务器地址
    ///   - params: ["flag":"","userId":""] - flag,userId       为上传的参数
    ///        flag - 666 信息上传多张   －000 头像上传
    ///   - data: image转换成Data
    ///   - name: fileName
    ///   - success:
    ///   - failture:、
    func upLoad( urlString: String,data: [Data],name: [String], parameters: [String : AnyObject]?, successCallBack: @escaping SuccessCallBack, failedCallBack: @escaping FailedCallBack) {
        let requestId = generateRequestId()
       
    
    
                let headers = ["content-type":"multipart/form-data"]
                Alamofire.upload(multipartFormData: { multipartFormData in
                    //666多张图片上传
        //            let flag = params!["flag"]
                    let userId = parameters!["userId"]
        
                    //参数的上传
        //            multipartFormData.append((flag?.data(using: String.Encoding.utf8.rawValue)!)!, withName: "flag")
                    multipartFormData.append( (userId?.data(using: String.Encoding.utf8.rawValue)!)!, withName: "userId")
        
                    //multipartFormData.append(<#T##data: Data##Data#>, withName: <#T##String#>, fileName: <#T##String#>, mimeType: <#T##String#>)  ---使用的方法
                    //遍历图片，挨个添加，withName-name和后台确定是什么
                    for i in 0..<data.count {
                        multipartFormData.append(data[i], withName: "appPhoto", fileName: name[i], mimeType: "image/png")
                    }
                },
                                 to: urlString,
                                 headers: headers,
                                 encodingCompletion: { encodingResult in
                                    switch encodingResult {
                                    case .success(let upload, _, _):
                                        upload.responseJSON { response in
                                            successCallBack(response as AnyObject, requestId)
                                        }
                                    case .failure(let encodingError):
                                        failedCallBack(encodingError as NSError, requestId)
                                    }
                }
                )
    }

    func requestFinished<T>(urlResponse: DataResponse<T>, requestId: NSNumber, successCallBack: SuccessCallBack, failedCallBack: FailedCallBack) {
        guard urlResponse.result.error == nil else {
            //deal with failure for request
            
            failedCallBack(urlResponse.result.error! as NSError, requestId)
            return
        }

            successCallBack(urlResponse as AnyObject, requestId)
    }
    
    //MARK: helper method
    func generateRequestId() -> NSNumber {
        
        guard let requestOrder = latestStoredRequestId else {
            latestStoredRequestId =
                
                NSNumber(value: 1)
            return latestStoredRequestId!
        }
        
        guard requestOrder.intValue < NSIntegerMax && requestOrder.intValue > 0 else {
            latestStoredRequestId = NSNumber(value: 1)
            return latestStoredRequestId!
        }
        
        latestStoredRequestId = NSNumber(value: requestOrder.intValue + 1);
        return latestStoredRequestId!;
    }
    
    //MARK: - life cycle
    deinit {
        self.cancellAllRequest()
    }
    
    //MARK: variables
    var latestStoredRequestId: NSNumber?
    var storedRequests = Dictionary<NSNumber, Request>()
    
    //singleton instance
//    private static var onceToken: dispatch_once_t = 0

    
    static let  sharedInstance = ApiProxy()
}
